package com.liyao.windowtest4.controller;

import com.liyao.windowtest4.Utils.GlobalConfig;
import com.liyao.windowtest4.pojo.DataRow;
import com.liyao.windowtest4.pojo.wrenchRow;
import com.liyao.windowtest4.service.loginService;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Callback;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.liyao.windowtest4.JavaFXApp.CORRECT_PASSWORD;
import static com.liyao.windowtest4.Utils.getWiFiName.getWiFiName;


/**
 * @program: windowtest4
 * @description:
 * @author: liu yan
 * @create: 2024-10-21 19:28
 */
@Controller
public class mainController {

    @Resource
    loginService service;

    @Value("${correct.DBstate}")
    private String dbstate;

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.password}")
    private String dbPass;

    @Value("${spring.datasource.username}")
    private String dbUser;


    @Value("${correct.TABLEName}")
    private String dbTable;

    public String getDbUrl() {
        return dbUrl;
    }

    public String getDbPass() {
        return dbPass;
    }

    public String getDbUser() {
        return dbUser;
    }

    public String getDbstate() {
        return dbstate;
    }

    public String getDbTable() {
        return dbTable;
    }

    @FXML
    public TableView<DataRow> dataTable;

    @FXML
    public MenuItem ting;
    @FXML
    public MenuItem pass;
    @FXML
    public TextField wifiName;
    public TextField barCodeInput;
    public String getBarCodeInput() {
        return barCodeInput.getText();
    }
    public TextField onlineSum;
    public VBox wrenchVBox;
    private List<wrenchRow> wrList;

    private Map<String, Label> labelMap = new HashMap<>();

    private ObservableList<DataRow> data = FXCollections.observableArrayList();

    private static final String CONFIG_FILE_PATH = System.getProperty("user.dir")+ File.separator + "config"+File.separator +"application.properties"; // 配置文件路径
    private static final String CORRECT_PASSWORD_KEY = "correct.password"; // 配置文件中的密码键

    public String wrenchLabel;



    @FXML
    private void initialize() {
        wifiName.setEditable(false);
        wifiName.setText(getWiFiName());
        onlineSum.setEditable(false);
        onlineSum.setText("0");

        getWrenchList();

        // 读取文件并填充数据

        String configDirPath = System.getProperty("user.dir") + File.separator + "config" + File.separator;
            try(BufferedReader br = new BufferedReader(new FileReader(configDirPath+"data.txt"))){
            if(br==null){
                System.err.println("未找到：data.txt 文件");
            }
            String line;
            while ((line = br.readLine()) != null) {
                if(line.length()>0){
                    JSONObject js= JSONObject.fromObject(line);

                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                    String date=sdf.format(new Date());

                    if(js.getString("date").equals(date)){
                        DataRow row = new DataRow(
                                js.getString("sequenceNumber").toString(),
                                js.getString("wrenchName").toString(),
                                js.getString("barCode").toString(),
                                js.getString("screwID").toString(),
                                js.getString("targetTorque").toString(),
                                js.getString("minTorque").toString(),
                                js.getString("maxTorque").toString(),
                                js.getString("value").toString(),
                                js.getString("outcomeCol").toString(),
                                js.getString("date").toString(),
                                js.getString("time").toString(),
                                Integer.parseInt(js.get("ordinalNumber").toString())
                        );
                        data.add(row);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            // 处理异常，例如显示错误消息
        }
        // 按照timestamp 时间倒序倒序排序
        Collections.sort(data, (d1, d2) -> d2.getOrdinalNumber().compareTo(d1.getOrdinalNumber()));

        // 设置表格的项为data列表
        dataTable.setItems(data);

        // 初始化表格列
        TableColumn<DataRow, String> sequenceNumberCol = new TableColumn<>("序号");
        sequenceNumberCol.setCellValueFactory(new PropertyValueFactory<>("sequenceNumber"));

        TableColumn<DataRow, String> wrenchNameCol = new TableColumn<>("扳手名称");
        wrenchNameCol.setCellValueFactory(new PropertyValueFactory<>("wrenchName"));

        TableColumn<DataRow, String> barCodeCol = new TableColumn<>("条码");
        barCodeCol.setCellValueFactory(new PropertyValueFactory<>("barCode"));

        TableColumn<DataRow, String> screwIDCol = new TableColumn<>("螺丝编号");
        screwIDCol.setCellValueFactory(new PropertyValueFactory<>("screwID"));

        TableColumn<DataRow, String> targetTorqueCol = new TableColumn<>("扭力标准");
        targetTorqueCol.setCellValueFactory(new PropertyValueFactory<>("targetTorque"));

        TableColumn<DataRow, String> minTorqueCol = new TableColumn<>("扭力下限");
        minTorqueCol.setCellValueFactory(new PropertyValueFactory<>("minTorque"));

        TableColumn<DataRow, String> maxTorqueCol = new TableColumn<>("扭力上限");
        maxTorqueCol.setCellValueFactory(new PropertyValueFactory<>("maxTorque"));

        TableColumn<DataRow, String> valueCol = new TableColumn<>("实测值");
        valueCol.setCellValueFactory(new PropertyValueFactory<>("value"));

        TableColumn<DataRow, String> outcomeCol = new TableColumn<>("判定");
        outcomeCol.setCellValueFactory(new PropertyValueFactory<>("outcomeCol"));

        // 创建自定义单元格工厂，用于设置特定列的单元格样式
        Callback<TableColumn<DataRow, String>, TableCell<DataRow, String>> cellFactory =
                new Callback<TableColumn<DataRow, String>, TableCell<DataRow, String>>() {
                    @Override
                    public TableCell<DataRow, String> call(TableColumn<DataRow, String> param) {
                        return new TableCell<DataRow, String>() {
                            @Override
                            protected void updateItem(String item, boolean empty) {
                                super.updateItem(item, empty);
                                if (empty || item == null) {
                                    setText(null);
                                    setStyle("");
                                } else {
                                    setText(item);
                                    // 根据值来设置字体颜色
                                    if ("NG".equals(item)) {
                                        setStyle("-fx-text-fill: red;");
                                    } else if ("OK".equals(item)) {
                                        setStyle("-fx-text-fill: green;");
                                    } else {
                                        // 其他情况可以设置默认颜色或者不设置（保持原有样式）
                                        setStyle("");
                                    }
                                }
                            }
                        };
                    }
                };

        // 将自定义单元格工厂应用到对应的列
        outcomeCol.setCellFactory(cellFactory);

        TableColumn<DataRow, String> date = new TableColumn<>("日期");
        date.setCellValueFactory(new PropertyValueFactory<>("date"));

        TableColumn<DataRow, String> time = new TableColumn<>("时间");
        time.setCellValueFactory(new PropertyValueFactory<>("time"));

        TableColumn<DataRow, String> ordinalNumberCol = new TableColumn<>("序数");
        ordinalNumberCol.setCellValueFactory(new PropertyValueFactory<>("ordinalNumber"));




        // 将列添加到表格中
        dataTable.getColumns().addAll(sequenceNumberCol, wrenchNameCol, barCodeCol, screwIDCol, targetTorqueCol, minTorqueCol, maxTorqueCol, valueCol, outcomeCol, date, time, ordinalNumberCol);
        dataTable.getStyleClass().add("table-cell");

        // 设置按钮的点击事件监听器

        ting.setOnAction(this::setting);
        pass.setOnAction(this::changePass);
    }


    @FXML
    public void addDataEvent(DataRow dataRow){
        System.out.println("data.size:"+data.size());
        if(null!=wrenchLabel && wrenchLabel.length()>0){
            if(dataRow.getWrenchName().equals(wrenchLabel)){
                data.add(0,dataRow);
            }
        }else{
            data.add(0, dataRow);
        }
    }

    @FXML
    private void setting(ActionEvent actionEvent) {
        Stage dialogStage = new Stage();
        dialogStage.initModality(Modality.APPLICATION_MODAL);
        dialogStage.initStyle(StageStyle.UTILITY);

        GridPane dialogPane = new GridPane();
        dialogPane.setPadding(new Insets(10));
        dialogPane.setVgap(8);
        dialogPane.setHgap(10);

        Label passwordLabel = new Label("密码:");
        PasswordField passwordField = new PasswordField();
        passwordField.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                try {
                    verifyPassword(passwordField.getText(),dialogStage);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        Button loginButton = new Button("登陆");
        loginButton.setOnAction(e -> {
            try {
                verifyPassword(passwordField.getText(),dialogStage);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        });

        dialogPane.add(passwordLabel, 0, 0);
        dialogPane.add(passwordField, 1, 0);
        dialogPane.add(loginButton, 1, 1);

        Scene dialogScene = new Scene(dialogPane, 250, 100);
        dialogStage.setScene(dialogScene);
        dialogStage.setTitle("输入密码");

        dialogStage.showAndWait();
    }

    private void verifyPassword(String password,Stage dialogStage) throws IOException {
        if (CORRECT_PASSWORD.equals(password)) {
            dialogStage.close();
            showNewWindow();
        } else {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("无效的密码");
            alert.setHeaderText(null);
            alert.setContentText("您输入的密码不正确");
            alert.showAndWait();
        }
    }

    private void showNewWindow() throws IOException {
        Stage newStage = new Stage();
        // 这里可以加载一个新的FXML文件或设置一个新的场景
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/management.fxml"));
        Parent bPageRoot = null;
        try {
            bPageRoot = loader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
        managementController bController = loader.getController();
        // 将数据传递给B页面的控制器
        bController.setDataItem(this);
        Scene newScene = new Scene(bPageRoot);
        newStage.setScene(newScene);
        newStage.show();
    }

    @FXML
    private void showAlert(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("信息");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.setResizable(false);

        Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
        stage.setAlwaysOnTop(true);

        alert.showAndWait();
    }

    @FXML
    private void changePass(ActionEvent actionEvent) {
        Stage dialogStage = new Stage();
        dialogStage.initModality(Modality.APPLICATION_MODAL);
        dialogStage.initStyle(StageStyle.UTILITY);

        GridPane dialogPane = new GridPane();
        dialogPane.setPadding(new Insets(10));
        dialogPane.setVgap(8);
        dialogPane.setHgap(10);

        Label oldPasswordLabel = new Label("原密码:");
        PasswordField oldPasswordField = new PasswordField();

        Label newPasswordLabel = new Label("新密码:");
        PasswordField newPasswordField = new PasswordField();

        Button confirmButton = new Button("修改");
        confirmButton.setOnAction(e -> {
            String oldPassword = oldPasswordField.getText();
            String newPassword = newPasswordField.getText();

            if (isCorrectPassword(oldPassword)) {
                updatePasswordInConfigFile(newPassword);
                Alert successAlert = new Alert(Alert.AlertType.INFORMATION);
                successAlert.setTitle("成功");
                successAlert.setHeaderText(null);
                successAlert.setContentText("密码修改成功，新密码在系统重启后生效！");
                successAlert.showAndWait();
                dialogStage.close();
            } else {
                Alert errorAlert = new Alert(Alert.AlertType.ERROR);
                errorAlert.setTitle("错误");
                errorAlert.setHeaderText(null);
                errorAlert.setContentText("旧密码识别错误！");
                errorAlert.showAndWait();
            }
        });

        dialogPane.add(oldPasswordLabel, 0, 0);
        dialogPane.add(oldPasswordField, 1, 0);
        dialogPane.add(newPasswordLabel, 0, 1);
        dialogPane.add(newPasswordField, 1, 1);
        dialogPane.add(confirmButton, 1, 2);

        Scene dialogScene = new Scene(dialogPane, 300, 150);
        dialogStage.setScene(dialogScene);
        dialogStage.setTitle("修改密码");

        dialogStage.showAndWait();
    }

    private boolean isCorrectPassword(String password) {
        return CORRECT_PASSWORD.equals(password);
    }

    private void updatePasswordInConfigFile(String newPassword) {
        Properties properties = new Properties();
        try (InputStream input = new FileInputStream(CONFIG_FILE_PATH)) {
            // 从配置文件中加载属性
            properties.load(input);
        } catch (IOException ex) {
            ex.printStackTrace();
            // 处理文件读取异常，例如显示错误消息等
            return;
        }

        // 更新密码属性
        properties.setProperty(CORRECT_PASSWORD_KEY, newPassword);

        try (OutputStream output = new FileOutputStream(CONFIG_FILE_PATH)) {
            // 将更新后的属性写回配置文件
            properties.store(output, null);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private List<String> wrenchIds=new ArrayList<>();

    private final List<WrenchTask> wrenchTasks = new ArrayList<>();
    private void getWrenchList(){
        System.out.println("执行力");
        // 创建config文件夹的路径
        String configDirPath = System.getProperty("user.dir") + File.separator + "config" + File.separator;
        try (BufferedReader br = new BufferedReader(new FileReader(configDirPath + "torqueItems.txt"))) {
//          try {
//              InputStream inputStream=getClass().getClassLoader().getResourceAsStream("torqueItems.txt");
              if(br==null){
                  System.err.println("未找到系统文件：torqueItems.txt");
              }
//              BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

              String line;
            List<String> allWrenchIds = new ArrayList<>();
            while ((line = br.readLine()) != null) {
                if(line.length()>0){
                    JSONObject js= JSONObject.fromObject(line);
                    try (BufferedReader br2 = new BufferedReader(new FileReader(configDirPath+"taskItems.txt"))) {
//                try{
//                    InputStream inputStream1=getClass().getClassLoader().getResourceAsStream("taskItems.txt");
                        if(br2==null){
                            System.err.println("未找到系统文件：taskItems.txt");
                        }
//                    BufferedReader br2 = new BufferedReader(new InputStreamReader(inputStream1));
                        String line2;
                        js.put("jobId","");
                        while ((line2 = br2.readLine()) != null){
                            if (line2.contains("\"SN\":\"" + js.getString("SN") + "\"")) {
                                JSONObject json=JSONObject.fromObject(line2);
                                js.put("jobId",json.getString("RoutineId"));
                                break;
                            }else{
                                js.put("jobId","");
                            }
                        }
                    }catch (IOException io){
                        System.out.println(io);
                        io.printStackTrace();
                    }
                    wrenchRow wr=new wrenchRow(js.getString("SN"),js.getString("TorqueName"), js.getString("Host"), js.getInt("Port"),js.getString("jobId"));
                    this.wrList=new ArrayList<>();
                    this.wrList.add(wr);

                    String TorqueName = js.getString("TorqueName");
                    String SN = js.getString("SN");
                    Label label = new Label(TorqueName);
                    label.setId(js.getString("SN"));
                    label.getStyleClass().add("dynamic-label-style");
                    label.setOnMouseClicked(new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent event) {
                            String labelValue = label.getText();
                            System.out.println("点击的Label值为: " + labelValue);
                            getOneWrenchData(labelValue);
                        }
                    });
                    WrenchTask wt=new WrenchTask();
                    wt.WrenchTaskInit(js.getString("TorqueName"), js.getString("Host"), js.getInt("Port"),this);
                    //wrenchIds.add(SN);
                    //wt.initializeWrenchInfo(wrenchIds);
                    wrenchTasks.add(wt);
                    //wt.startAllWrenchTasks(wrenchIds);
                    wt.start(SN);
                    GlobalConfig.setWrenchTask(SN,wt);
                    wrenchVBox.getChildren().add(label);
                    System.out.println("已经添加了label");

                    // 将 Label 存储在 Map 中
                    labelMap.put(SN, label);
                    allWrenchIds.add(SN);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println(e);
            // 处理异常，例如显示错误消息
        }
    }

    public void addWrenchList(String SN,String host,int Port){
        Label label = new Label(SN);
        label.setId(SN);
        label.getStyleClass().add("dynamic-label-style");
        wrenchVBox.getChildren().add(label);
        labelMap.put(SN, label);
        WrenchTask wt=new WrenchTask();
        wt.WrenchTaskInit(SN,host,Port,this);
        wrenchTasks.add(wt);
        wt.start(SN);
        GlobalConfig.setWrenchTask(SN,wt);
    }

    public void setOnlineSum(String wrenchId,boolean state){
        if(state){
            if(!wrenchIds.contains(wrenchId)){
                wrenchIds.add(wrenchId);
            }
        }else{
            wrenchIds.remove(wrenchId);
        }
        onlineSum.setText(wrenchIds.size()+"");

    }

    public void setLabelStyle(String wrenchId,String style){
        System.out.println("扳手ID："+wrenchId);
        Label label=labelMap.get(wrenchId);
        label.setStyle(style);
    }



    public void login(ActionEvent actionEvent) {
        System.out.println("数据库");
        System.out.println("数据库状态："+dbstate);
        try{
            service.getUserMes("123","123");
        }catch (Exception e){
            System.out.println("shujuku :"+e);
        }
    }

    public void removeWrenchTask(String targetCode) {
        WrenchTask wrenchTask=GlobalConfig.getWrenchTask(targetCode);
        wrenchTask.stop();
        wrenchVBox.getChildren().remove(labelMap.get(targetCode));
        labelMap.remove(targetCode);
    }

    public void test(ActionEvent actionEvent) throws IOException {
        System.out.println("nihao:"+this.getBarCodeInput());
        WrenchTask wrenchTask=new WrenchTask();
        wrenchTask.WriteTxt2("扳手名称","10.0",this);
    }

    public void getOneWrenchData(String wrenchLabelText){
        this.wrenchLabel=wrenchLabelText;
        this.data = FXCollections.observableArrayList();

        String configDirPath = System.getProperty("user.dir") + File.separator + "config" + File.separator;
        try(BufferedReader br = new BufferedReader(new FileReader(configDirPath+"data.txt"))){
            if(br==null){
                System.err.println("未找到：data.txt 文件");
            }
            String line;
            while ((line = br.readLine()) != null) {
                if(line.length()>0){
                    JSONObject js= JSONObject.fromObject(line);

                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                    String date=sdf.format(new Date());

                    if(js.getString("timestamp").substring(0,10).equals(date) && js.get("wrenchName").equals(wrenchLabelText)){
                        DataRow row = new DataRow(
                                js.getString("sequenceNumber").toString(),
                                js.getString("wrenchName").toString(),
                                js.getString("barCode").toString(),
                                js.getString("screwID").toString(),
                                js.getString("targetTorque").toString(),
                                js.getString("minTorque").toString(),
                                js.getString("maxTorque").toString(),
                                js.getString("value").toString(),
                                js.getString("outcomeCol").toString(),
                                js.getString("data").toString(),
                                js.getString("time").toString(),
                                Integer.parseInt(js.get("ordinalNumber").toString())
                        );
                        data.add(row);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            // 处理异常，例如显示错误消息
        }
        // 按照timestamp 时间倒序倒序排序
        Collections.sort(data, (d1, d2) -> d2.getOrdinalNumber().compareTo(d1.getOrdinalNumber()));

        // 设置表格的项为data列表
        dataTable.setItems(data);
    }
}
